<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tiktok商户配置工具-v{{version}}</title>
    <link href="/css/bootstrap.min.css" rel="stylesheet">
    <script src="/js/vue.global.min.js"></script>
    <script src="/js/bootstrap.bundle.min.js"></script>
    <style>
        .container { margin-top: 30px; }
        .form-group { margin-bottom: 1rem; }
        [v-cloak] { display: none; }
        .product-list { margin-top: 30px; }
        .product-item { 
            padding: 10px 15px; 
            border-bottom: 1px solid #eee;
            transition: background-color 0.3s;
        }
        .product-item.exist-discount { background-color: #f5f5f5; }
        .product-image { width: 50px; height: 50px; object-fit: cover; }
        .product-info { margin-left: 15px; }
        .product-input {
            width: 100% !important;
            padding: 0.25rem 0.5rem;
            font-size: 0.875rem;
        }
        .product-checkbox {
            width: 20px;
            height: 20px;
        }
        .modal-backdrop {
            background-color: rgba(0, 0, 0, 0.5);
        }
        .preview-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 1050;
        }
        .preview-content {
            background: white;
            padding: 20px;
            border-radius: 8px;
            width: 90%;
            max-width: 1200px;
            max-height: 90vh;
            overflow-y: auto;
        }
        .highlight-cell {
            background-color: #fff3cd;
            font-weight: bold;
        }
        .sku-table th, .sku-table td {
            padding: 8px;
            vertical-align: middle;
        }
        .close-btn {
            position: absolute;
            right: 20px;
            top: 20px;
        }
        .out-of-stock { background-color: #ebee2d; }
        .ready { background-color: #1ebda8; }
    </style>
</head>
<body>
    <div id="app" class="container" v-cloak>
        <div v-if="!hasSession">
            <div class="card">
                <div class="card-header">
                    <h2 class="mb-0">账号配置</h2>
                </div>
                <div class="card-body">
                    <form @submit.prevent="loadCountries">
                        <div class="row mb-4" v-if="!hasToken">
                            <div class="col-md-2">
                                <label class="form-label">授权码</label>
                            </div>
                            <div class="col-md-10">
                                <textarea class="form-control" rows="3" v-model="token" required></textarea>
                            </div>
                        </div>
                        <div class="row mb-4">
                            <div class="col-md-2">
                                <label class="form-label">Tiktok账号SessionId</label>
                            </div>
                            <div class="col-md-10">
                                <input type="text" class="form-control" v-model="sessionId" required>
                            </div>
                        </div>
                        <div class="row mb-4">
                            <div class="col-md-2">
                                <label class="form-label">妙手账号配置</label>
                            </div>
                            <div class="col-md-10">
                                <div class="card">
                                    <div class="card-body">
                                        <ul class="nav nav-tabs mb-3" id="msConfigTabs" role="tablist">
                                            <li class="nav-item" role="presentation">
                                                <button class="nav-link" :class="{ active: activeTab === 'manual' }" @click="activeTab = 'manual'" type="button" role="tab">手动获取</button>
                                            </li>
                                            <li class="nav-item" role="presentation">
                                                <button class="nav-link" :class="{ active: activeTab === 'auto' }" @click="activeTab = 'auto'" type="button" role="tab">用户名密码</button>
                                            </li>
                                        </ul>
                                        <div class="tab-content" id="msConfigTabContent">
                                            <div class="tab-pane" :class="{ 'show active': activeTab === 'auto' }" id="auto" role="tabpanel">
                                                <div class="row mb-3">
                                                    <div class="col-md-6">
                                                        <label class="form-label">用户名</label>
                                                        <input type="text" class="form-control" v-model="msUsername">
                                                    </div>
                                                    <div class="col-md-6">
                                                        <label class="form-label">密码</label>
                                                        <input type="text" class="form-control" v-model="msPassword">
                                                    </div>
                                                </div>
                                                <button class="btn btn-primary" @click="autoGetMsToken" :disabled="msLoading">
                                                    <span v-if="msLoading" class="spinner-border spinner-border-sm me-1"></span>
                                                    自动获取
                                                </button>
                                            </div>
                                            <div class="tab-pane" :class="{ 'show active': activeTab === 'manual' }" id="manual" role="tabpanel">
                                                <div class="row mb-3">
                                                    <div class="col-12">
                                                        <label class="form-label">autoLoginToken</label>
                                                        <textarea class="form-control" rows="3" v-model="msLoginToken" placeholder="请粘贴autoLoginToken"></textarea>
                                                    </div>
                                                </div>
                                                <div class="row">
                                                    <div class="col-12">
                                                        <label class="form-label">mserp</label>
                                                        <textarea class="form-control" rows="3" v-model="mserp" placeholder="请粘贴mserp"></textarea>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-2"></div>
                            <div class="col-md-10">
                                <button type="submit" class="btn btn-primary">进入账号</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>

            <div class="card mt-4">
                <div class="card-header">
                    <h5 class="mb-0">账号获取说明</h5>
                </div>
                <div class="card-body">
                    <div class="alert alert-warning mb-3">
                        <strong>注意：</strong> 如果在浏览器中退出了TikTokShop的账号，则此处录入的sessionId也会跟着失效，必须重新登录并获取账号才能继续使用
                    </div>
                    <div class="mb-3">
                        <h6>账号获取流程：</h6>
                        <ol class="mb-3">
                            <li>使用Chrome浏览器打开(<a href="https://seller.tiktokglobalshop.com/account/login" target="_blank">TikTokShop管理后台</a>)，登录账号</li>
                            <li>按下F12打开调度工具, 或者在页面上单击鼠标右键然后选择[检查]</li>
                            <li>按下图指引找到登录凭证，tiktok账号的查找 sessionid , 妙手账号查找 autoLoginToken和mserp</li>
                            <li>找到后再次按下F12关闭调试工具</li>
                        </ol>
                    </div>
                    <div class="row">
                        <div class="col-md-6 mb-3">
                            <img src="images/open_developer_tool.png" alt="打开开发者工具" class="img-fluid rounded">
                        </div>
                        <div class="col-md-6 mb-3">
                            <img src="images/get_session.png" alt="获取Session" class="img-fluid rounded">
                        </div>
                        <div class="col-12">
                            <div class="mb-2">中文界面参照下图：</div>
                            <img src="images/get_session_cn.png" alt="中文界面" class="img-fluid rounded">
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div v-if="hasSession">
            <div class="row mb-3">
                <div class="row">
                    <div class="col-2 mb-0">
                        <h2>
                            参数配置
                        </h2>
                    </div>
                    <div class="col-8">
                        <button type="button" class="btn btn-primary btn-sm ms-2" @click="hasSession=false;products=[];productLoaded=false">返回账号配置</button>
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <div class="card">
                        <div class="card-header">
                            <div class="row align-items-center">
                                <div class="col-md-6">
                                    <select v-model="selectedCountry" class="form-select" @change="handleCountryChange">
                                        <option v-for="(info, code) in countries" :key="code" :value="code">[[info.name || code]]</option>
                                    </select>
                                </div>
                                <div class="col-md-6 text-end">
                                    <button type="button" class="btn btn-primary btn-sm ms-2" @click="confirmFormula">保存配置</button>
                                </div>
                            </div>
                        </div>
                        <div class="card-body">
                            <form>
                                <div class="row mb-3">
                                    <div class="col-12">
                                        <div class="input-group">
                                            <span class="input-group-text">价格计算公式</span>
                                            <input type="text" 
                                                   class="form-control" 
                                                   v-model="priceFormula" 
                                                   @change="parseFormula"
                                                   placeholder="例如：（<采集价> + {贴单费}) x {汇率} x {增益定价比} + (物流起步价 + <克重> x  {克重单价} )">
                                        </div>
                                        <div class="form-text text-danger" v-if="formulaError">[[formulaError]]</div>
                                    </div>
                                </div>
                                <div class="row mb-3" v-if="formulaConstants && Object.keys(formulaConstants).length > 0">
                                    <div class="col-12">
                                        <h6 class="mb-2">常量参数配置</h6>
                                        <div class="row g-2">
                                            <div v-for="(value, key) in formulaConstants" :key="key" class="col-md-4">
                                                <div class="input-group input-group-sm">
                                                    <span class="input-group-text">[[key]]</span>
                                                    <input type="number" 
                                                           class="form-control" 
                                                           v-model="formulaConstants[key]" 
                                                           step="0.0001" 
                                                           @input="calculateTestResult"
                                                           @blur="calculateTestResult"
                                                           @change="calculateTestResult"
                                                           required>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="row mb-3" v-if="formulaValid">
                                    <div class="col-12">
                                        <h6 class="mb-2">公式验证</h6>
                                        <div class="row g-2">
                                            <div class="col-md-3">
                                                <div class="input-group input-group-sm">
                                                    <span class="input-group-text">采集价（￥）</span>
                                                    <input type="number" 
                                                           class="form-control" 
                                                           v-model="testValues.collectionPrice" 
                                                           step="1"
                                                           @input="calculateTestResult"
                                                           @blur="calculateTestResult"
                                                           @change="calculateTestResult">
                                                </div>
                                            </div>
                                            <div class="col-md-2">
                                                <div class="input-group input-group-sm">
                                                    <span class="input-group-text">克重</span>
                                                    <input type="number" 
                                                           class="form-control" 
                                                           v-model="testValues.weight" 
                                                           step="1" 
                                                           @input="calculateTestResult"
                                                           @blur="calculateTestResult"
                                                           @change="calculateTestResult">
                                                </div>
                                            </div>
                                            
                                            <div class="col-md-3">
                                                <div class="input-group input-group-sm">
                                                    <span class="input-group-text">优惠券</span>
                                                    <input type="number" 
                                                           class="form-control" 
                                                           v-model="testValues.couponAmount" 
                                                           step="1" 
                                                           @input="calculateTestResult"
                                                           @blur="calculateTestResult"
                                                           @change="calculateTestResult">
                                                </div>
                                            </div>
                                            <div class="col-md-2">
                                                <div class="input-group input-group-sm">
                                                    <span class="input-group-text">计算结果</span>
                                                    <input type="number" 
                                                           class="form-control" 
                                                           v-model="testResult" 
                                                           readonly>
                                                </div>
                                            </div>
                                            <div class="col-md-2">
                                                <button type="button" 
                                                        class="btn btn-danger btn-sm w-100" 
                                                        @click="confirmFormula"
                                                        v-if="hasFormulaChanged">
                                                    确认并保存配置
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
            <button type="button" class="btn btn-primary btn-sm ms-2 mt-3" @click="loadProducts()">加载产品↓</button>
        </div>
        <!-- 产品列表模块 -->
        <div class="product-list" v-show="productLoading || productLoaded">
            <h3 class="mb-4">产品列表([[products.length]])</h3>
            <!-- 添加统计信息和下载按钮 -->
            <div class="d-flex flex-column align-items-end gap-2 mb-3">
                <div class="text-end alert alert-info" v-if="stats.configuredProducts > 0">
                    <div>产品数量:[[stats.configuredProducts]]，产品规格数量:[[stats.totalSkus]]</div>
                </div>
                <div class="d-flex gap-2">
                    <div class="d-flex align-items-center">
                        <label class="me-2">优惠券金额：</label>
                        <input type="number" 
                               class="form-control" 
                               style="width: 100px"
                               v-model="couponAmount">
                    </div>
                    <button class="btn btn-outline-primary" @click="downloadKillConfig">
                        下载秒杀配置
                    </button>
                    <button class="btn btn-outline-primary" @click="downloadDiscountConfig">
                        下载折扣配置
                    </button>
                </div>
            </div>
            <div class="card">
                <div class="card-body">
                    <div v-if="products.length === 0" class="text-center py-3">
                        [[productLoading ? '加载中...' : '暂无产品数据']]
                    </div>
                    <div v-else>
                        
                        <div class="d-flex align-items-center fw-bold mb-2 px-2">
                            <div style="width: 20px"></div>
                            <div style="width: 50px"></div>
                            <div class="flex-grow-1">产品信息</div>
                            <div style="width: 120px" class="text-center">克重</div>
                            <div style="width: 120px" class="text-center">价格 (¥)</div>
                            <div style="width: 100px"></div>
                            <div style="width: 100px"></div>
                        </div>
                        <div v-for="product in products" 
                             :key="product.id" 
                             class="product-item d-flex align-items-center"
                             :class="{ 'exist-discount': product.exist_discount, 'out-of-stock': product.price === -1, 'ready': product.price > 0 && product.weight > 0}">
                            <input type="checkbox" 
                                   class="product-checkbox me-3" 
                                   :checked="product.price > 0 && product.weight > 0"
                                   disabled>
                            <img :src="product.thumbnail" :alt="product.id" class="product-image">
                            <div class="product-info flex-grow-1">
                                <div>ID: [[product.product_id]] |  [[product.min_price]] ~ [[product.max_price]](引流价: [[product.promote_price||'无']]) | 
                                    <a v-if="product.source_url" :href="product.source_url" target="_blank" class="text-primary small"> [[product.source]] >> 查看</a>
                                    <span class="text-danger" v-else>妙手数据未查到</span>
                                </div>
                                <div>
                                    <span class="text-danger small" v-if="product.exist_discount">折扣进行中</span>
                                </div>
                            </div>
                            <div style="width: 180px" class="px-2">
                                <input type="number" 
                                       class="form-control product-input" 
                                       v-model="product.weight" 
                                       placeholder="未获取"
                                       disabled="true"
                                       @change="handleProductUpdate(product)">
                            </div>
                            <div style="width: 120px; flex: row;" class="px-2 position-relative">
                                <input type="number" 
                                       class="form-control product-input" 
                                       v-model="product.price" 
                                       @change="handleProductUpdate(product)"
                                       @blur="previewProduct(product, false)"
                                       :disabled="product.price == -1">
                                <div v-if="product.loading" 
                                     class="position-absolute text-primary" 
                                     style="font-size: 12px; right: 10px; top: 50%; transform: translateY(-50%)">
                                    处理中...
                                </div>
                            </div>
                            <div style="width: 100px" class="text-end">
                                <button class="btn btn-sm btn-outline-primary" 
                                        @click="previewProduct(product)">
                                    预览
                                </button>
                            </div>
                            <div style="width: 100px" class="text-end">
                                <input type="checkbox" 
                                       class="form-check-input" 
                                       v-model="product.out_of_stock" 
                                       :checked="product.price === -1"
                                       @change="markOutOfStock(product)">
                                无货
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 预览弹窗 -->
        <div v-if="showPreview" class="preview-modal" @click="clickBlankToClose">
            <div class="preview-content position-relative">
                <button @click="showPreview = false" class="btn-close close-btn"></button>
                <h4 class="mb-4">营销预览</h4>
                <div class="mt-1">产品ID: [[previewData.product_id]] | 采集价(￥): [[previewData.price]] | 重量(g): [[previewData.weight]] | 优惠券: [[previewData.coupon_fee]]</div>
                <div v-if="previewData.price > 0">秒杀价: [[previewData.kill_price_formula]] = [[previewData.kill_price]]</div>
                <div v-if="previewData.price > 0">折扣计算: [[previewData.kill_rate_formula]]</div>
                <div class="table-responsive padding-top-10">
                    <table class="table table-bordered table-hover sku-table">
                        <thead class="table-light">
                            <tr>
                                <th>SKU ID</th>
                                <th>规格</th>
                                <th>库存</th>
                                <th>售价</th>
                                <th class="highlight-cell">秒杀价(折扣)</th>
                                <th class="highlight-cell">折扣</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="sku in previewData.skus" :key="sku.sku_id">
                                <td>[[sku.sku_id]]</td>
                                <td>[[sku.sku_name]]</td>
                                <td>[[sku.inventory_quantity]]</td>
                                <td>[[sku.sale_price]]</td>
                                <td class="highlight-cell" v-if="sku.kill_price">
                                    <span v-if="previewData.price > 0">[[sku.kill_price]]([[sku.kill_rate]]%)</span>
                                </td>
                                <td class="highlight-cell" v-else>
                                    <span v-if="previewData.price > 0">无</span>
                                </td>
                                <td class="highlight-cell">
                                    <span v-if="previewData.price > 0">[[sku.discount_rate||'无']]</span>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 添加全局fetch拦截器
        const originalFetch = window.fetch;
        window.fetch = async function(url, options = {}) {
            try {
                // 请求拦截
                const token = localStorage.getItem('auth_token');
                if (token) {
                    options.headers = options.headers || {};
                    options.headers['Authorization'] = token;
                }

                // 发送请求
                const response = await originalFetch(url, options);
                
                // 克隆响应以避免消费原始响应流
                const clonedResponse = response.clone();

                if (response.status === 401) {
                    alert('授权码无效或已过期，请重新配置');
                    localStorage.removeItem('auth_token');
                    window.location.reload();
                    return;
                }
                
                // 检查响应的Content-Type
                const contentType = response.headers.get('content-type');
                if (contentType && contentType.includes('application/json')) {
                    try {
                        // 只对JSON响应进行解析和检查
                        const data = await clonedResponse.json();
                        if (data.code !== 0) {
                            throw new Error(data.msg || '请求失败');
                        }
                    } catch (error) {
                        throw error;
                    }
                }
                
                return response;
            } catch (error) {
                alert(error.message);
            }
        };

        const { createApp, ref, reactive, onMounted, watch } = Vue;

        createApp({
            delimiters: ['[[', ']]'],
            setup() {
                const hasSession = ref(false)
                const hasToken = ref(false)
                const token = ref('');
                const sessionId = ref('');
                const msLoginToken = ref('');
                const mserp = ref('');
                const countries = ref({});
                const selectedShop = ref({});
                const selectedCountry = ref('');
                const countryConfig = ref({})
                const products = ref([]);
                const productLoading = ref(false);
                const productLoaded = ref(false);
                const couponAmount = ref(0);
                const showPreview = ref(false);
                const previewData = ref([]);
                const stats = reactive({
                    configuredProducts: 0,
                    totalSkus: 0
                });
                const config = reactive({
                    exchangeRate: '',
                    profitRatio: '',
                    baseShippingFee: '',
                    weightPrice: '',
                    labelFee: '',
                    couponAmount: ''
                });
                const msUsername = ref('');
                const msPassword = ref('');
                const msLoading = ref(false);
                const activeTab = ref('manual');
                const priceFormula = ref('');
                const formulaConstants = reactive({});
                const formulaValid = ref(false);
                const formulaError = ref('');
                const testValues = reactive({
                    collectionPrice: 10,
                    weight: 100,
                    couponAmount: 10
                });
                const testResult = ref(0);
                const hasFormulaChanged = ref(false);
                
                function clickBlankToClose(event) {
                    // 如果点击的是 preview-modal 区域（而不是 preview-content），则关闭弹窗
                    if (event.target.classList.contains('preview-modal')) {
                        showPreview.value = false;
                    }
                }

                // 保存数据到本地存储
                function saveToLocalStorage() {
                    try {
                        // 保存选中的国家
                        if (selectedCountry.value) {
                            localStorage.setItem('selectedCountry', selectedCountry.value);
                        }

                        // 只保存产品的必要信息
                        let cachedProducts =  loadCachedProducts();
                        products.value.forEach(product => {
                            if (product.price !=0) {
                                cachedProducts[product.source_item_id] = {
                                    price: product.price,
                                    weight: product.weight
                                };
                            } else {
                                delete cachedProducts[product.product_id];
                            }
                        });
                        localStorage.setItem('product_prices', JSON.stringify(cachedProducts));
                    } catch (error) {
                        console.error('保存数据到本地存储失败：', error);
                    }
                }

                function loadCachedProducts(){
                    const cache = localStorage.getItem('product_prices');
                    if(cache) {
                        return JSON.parse(cache)
                    } else {
                        return {}
                    }
                }

                // 手动选择国家时触发
                async function handleCountryChange() {
                    productLoaded.value = false;
                    await loadCountryConfig();
                    couponAmount.value = 0;
                    saveToLocalStorage(); // 只在手动选择时保存
                }

                // 手动更新产品信息时触发
                function handleProductUpdate(product) {
                    saveToLocalStorage(); // 只在手动更新时保存
                }

                async function loadCountries() {
                    if (!sessionId.value) {
                        alert('请输入sessionId');
                        return
                    }
                    if (!msLoginToken.value) {
                        alert('请输入autoLoginToken');
                        return
                    }
                    if (!mserp.value) {
                        alert('请输入mserp');
                        return
                    }
                    // 保存token到localStorage
                    localStorage.setItem('auth_token', token.value);
                    
                    const response = await fetch(`/configs?session_id=${sessionId.value}`);
                    const result = await response.json();
                    if (result.code === 0) {
                        countries.value = result.data;
                        const savedCountry = localStorage.getItem('selectedCountry');
                        
                        if (savedCountry && result.data[savedCountry]) {
                            selectedCountry.value = savedCountry;
                        } else {
                            const firstCountry = Object.keys(result.data)[0];
                            if (firstCountry) {
                                selectedCountry.value = firstCountry;
                            }
                        }
                        if (selectedCountry.value) {
                            await loadCountryConfig();
                        }
                        localStorage.setItem('sessionId', sessionId.value);
                        localStorage.setItem('msLoginToken', msLoginToken.value);
                        localStorage.setItem('mserp', mserp.value);
                        hasSession.value = true;
                    }
                    
                }

                async function loadCountryConfig() {
                    if (!selectedCountry.value) return;
                    products.value = [];
                    priceFormula.value = '';
                    try {
                        const response = await fetch('/configs?session_id=' + sessionId.value);
                        const result = await response.json();
                        
                        if (result.code === 0) {
                            countryConfig.value = result.data[selectedCountry.value]?.config || {};
                            selectedShop.value = result.data[selectedCountry.value]?.shop || {};
                            
                            // 如果有保存的公式，先设置公式
                            if (countryConfig.value.formula) {
                                priceFormula.value = countryConfig.value.formula;
                            } else {
                                priceFormula.value = '(<<采集价>> + {贴单费}) * {汇率} * {增益定价比} + ({物流起步价} + <<克重>> * {克重单价}) + <<优惠券>>';
                            }
                            parseFormula();
                            
                            calculateTestResult();
                        }
                    } catch (error) {
                        console.log(error)
                        alert('加载配置失败：' + error.message);
                    }
                }

                async function loadProducts() {
                    if (hasFormulaChanged.value) {
                        alert('请先确认并保存配置');
                        return;
                    }
                    
                    try {
                        products.value = [];
                        productLoading.value = true;
                        const response = await fetch(`/products?session_id=${sessionId.value}&mserp=${mserp.value}&ms_login_token=${msLoginToken.value}&shop_id=${selectedShop.value.outer_shop_id}&limit=1000`);
                        const result = await response.json();
                        
                        if (result.code === 0) {
                            const cachedProducts =  loadCachedProducts();
                            // 合并服务器数据和本地存储的数据
                            products.value = result.data.map(product => {
                                const savedProduct = cachedProducts[product.source_item_id];
                                return {
                                    ...product,
                                    price: savedProduct ? savedProduct.price : 0,
                                    weight: savedProduct ? savedProduct.weight : '',
                                    loading: false,
                                    skus: product.skus || [] // 初始化skus
                                };
                            });
                            
                            couponAmount.value = result.coupon_amount;
                            // 加载完成后立即更新统计信息
                            await updateStats();
                            productLoading.value = false;
                            productLoaded.value = true;
                        } else {
                            console.error('加载产品列表失败：', result.msg);
                            alert(result.msg);
                            productLoading.value = false;
                        }
                    } catch (error) {
                        console.error('加载产品列表失败：', error);
                        alert(error.message);
                        productLoading.value = false;
                    }
                }

                async function updateStats() {
                    // 统计已配置的产品数量
                    stats.configuredProducts = products.value.filter(p => p.price > 0).length;
                    
                    // 统计总规格数量
                    stats.totalSkus = products.value.reduce((total, product) => {
                        if (product.price > 0 && product.skus) {
                            return total + product.skus.length;
                        }
                        return total;
                    }, 0);
                }

                async function previewProduct(product, showPreviewWindow = true) {
                    if (hasFormulaChanged.value) {
                        alert('请先确认并保存配置');
                        return;
                    }
                    try {
                        // 设置loading状态
                        product.loading = true;
                        
                        const response = await fetch(`/marketing_preview?session_id=${sessionId.value}`, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json'
                            },
                            body: JSON.stringify({
                                country: selectedCountry.value,
                                shop_id: selectedShop.value.outer_shop_id,
                                product: product,
                                coupon_amount: couponAmount.value
                            })
                        });
                        
                        const result = await response.json();
                        if (result.code === 0) {
                            previewData.value = result.data;
                            product.weight = result.data.weight;
                            product.skus = result.data.skus; // 保存SKU信息
                            saveToLocalStorage();
                            if (showPreviewWindow) {
                                showPreview.value = true;
                            }
                            // 更新统计信息
                            await updateStats();
                        } else {
                            alert('获取预览失败：' + result.msg);
                        }
                    } catch (error) {
                        alert('获取预览失败：' + error.message);
                    } finally {
                        // 清除loading状态
                        product.loading = false;
                    }
                }

                function getTimeString(timestamp) {
                    const now = new Date();
                    const time_string = [
                        now.getFullYear(),
                        String(now.getMonth() + 1).padStart(2, '0'), // 月份补零
                        String(now.getDate()).padStart(2, '0'),     // 日期补零
                        String(now.getHours()).padStart(2, '0'),     // 小时补零
                        String(now.getMinutes()).padStart(2, '0'),   // 分钟补零
                        String(now.getSeconds()).padStart(2, '0')    // 秒补零
                    ].join('');
                    return time_string;
                }

                // 添加下载函数
                async function downloadKillConfig() {
                    if (hasFormulaChanged.value) {
                        alert('请先确认并保存配置');
                        return;
                    }
                    try {
                        const response = await fetch(`/download_kill_config?session_id=${sessionId.value}`, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json'
                            },
                            body: JSON.stringify({
                                country: selectedCountry.value,
                                shop_id: selectedShop.value.outer_shop_id,
                                products: products.value.filter(p => p.price > 0 && p.weight > 0),
                                coupon_amount: couponAmount.value
                            })
                        });
                        const blob = await response.blob();
                        const url = window.URL.createObjectURL(blob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = `[${selectedCountry.value}]秒杀配置_${getTimeString()}.xlsx`;
                        document.body.appendChild(a);
                        a.click();
                        window.URL.revokeObjectURL(url);
                        document.body.removeChild(a);
                    } catch (error) {
                        alert('下载秒杀配置失败：' + error.message);
                    }
                }

                async function downloadDiscountConfig() {
                    if (hasFormulaChanged.value) {
                        alert('请先确认并保存配置');
                        return;
                    }
                    try {
                        const response = await fetch(`/download_discount_config?session_id=${sessionId.value}`, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json'
                            },
                            body: JSON.stringify({
                                country: selectedCountry.value,
                                shop_id: selectedShop.value.outer_shop_id,
                                products: products.value.filter(p => p.price > 0 && p.weight > 0),
                                coupon_amount: couponAmount.value
                            })
                        });
                        const blob = await response.blob();
                        const url = window.URL.createObjectURL(blob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = `[${selectedCountry.value}]折扣配置_${getTimeString()}.xlsx`;
                        document.body.appendChild(a);
                        a.click();
                        window.URL.revokeObjectURL(url);
                        document.body.removeChild(a);
                    } catch (error) {
                        alert('下载折扣配置失败：' + error.message);
                    }
                }

                function markOutOfStock(product) {
                    if (product.out_of_stock) {
                        product.price = -1;
                    } else {
                        product.price = 0; // or any default value
                    }
                    updateStats();
                    handleProductUpdate(product);
                }

                // 自动获取妙手token
                async function autoGetMsToken() {
                    if (!msUsername.value || !msPassword.value) {
                        alert('请输入用户名和密码');
                        return;
                    }
                    localStorage.setItem('msUsername', msUsername.value);
                    localStorage.setItem('msPassword', msPassword.value);
                    msLoading.value = true;
                    try {
                        const response = await fetch('/ms_login', {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json'
                            },
                            body: JSON.stringify({
                                username: msUsername.value,
                                password: msPassword.value
                            })
                        });
                        const result = await response.json();
                        if (result.code === 0) {
                            msLoginToken.value = result.data.token;
                            mserp.value = result.data.mserp;
                            alert('登录成功');
                            activeTab.value = 'manual';
                        } else {
                            alert('登录失败：' + result.msg);
                        }
                    } catch (error) {
                        alert('获取失败：' + error.message);
                    } finally {
                        msLoading.value = false;
                    }
                }

                function parseFormula() {
                    formulaError.value = '';
                    formulaValid.value = false;
                    try {
                        // 检查是否包含必要的变量
                        if (!priceFormula.value.includes('<<采集价>>')) {
                            formulaError.value = '公式中必须包含<<采集价>>变量';
                            formulaValid.value = false;
                            return;
                        }
                        if (!priceFormula.value.includes('<<克重>>')) {
                            formulaError.value = '公式中必须包含<<克重>>变量';
                            formulaValid.value = false;
                            return;
                        }
                        if (!priceFormula.value.includes('<<优惠券>>')) {
                            formulaError.value = '公式中必须包含<<优惠券>>变量';
                            formulaValid.value = false;
                            return;
                        }

                        // 提取所有常量参数
                        const constantMatches = priceFormula.value.match(/\{([^}]+)\}/g) || [];
                        constantMatches.forEach(match => {
                            const key = match.slice(1, -1);
                            if (countryConfig.value[key] !== undefined) {
                                formulaConstants[key] = countryConfig.value[key];
                            } else {
                                formulaConstants[key] = '';
                            }
                        });

                        // 验证公式是否可计算
                        const testFormula = priceFormula.value
                            .replace(/\{([^}]+)\}/g, '1')  // 替换所有常量参数为1
                            .replace('<<采集价>>', '100')   // 替换采集价为100
                            .replace('<<克重>>', '1000')   // 替换克重为1000
                            .replace('<<优惠券>>', '10');   // 替换优惠券为10
                        try {
                            new Function('return ' + testFormula)();
                            formulaError.value = '';
                            formulaValid.value = true;
                        } catch (error) {
                            formulaError.value = '公式格式错误，请检查';
                            formulaValid.value = false;
                        }
                    } catch (error) {
                        console.log(error)
                        formulaError.value = '公式解析失败';
                        formulaValid.value = false;
                    }
                }

                function calculateTestResult() {
                    if (!formulaValid.value) return;
                    
                    try {
                        const formula = priceFormula.value
                            .replace(/\{([^}]+)\}/g, (match, key) => formulaConstants[key] || 0)
                            .replace('<<采集价>>', testValues.collectionPrice)
                            .replace('<<优惠券>>', testValues.couponAmount)
                            .replace('<<克重>>', testValues.weight);

                        const result = new Function('return ' + formula)().toFixed(2);
                        if (testResult.value!=0 && result!=testResult.value) {
                            hasFormulaChanged.value = true;
                        }
                        testResult.value = result;
                    } catch (error) {
                        testResult.value = '计算错误';
                    }
                }

                async function confirmFormula() {
                    if (!formulaValid.value) {
                        alert('请检查公式');
                        return;
                    };
                    
                    try {
                        const saveData = {
                            formula: priceFormula.value,
                            ...formulaConstants
                        };
                        
                        const response = await fetch('/configs/' + selectedCountry.value, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json'
                            },
                            body: JSON.stringify(saveData)
                        });
                        
                        const result = await response.json();
                        if (result.code === 0) {
                            hasFormulaChanged.value = false;
                            alert('配置已保存');
                        } else {
                            alert('保存失败：' + result.msg);
                        }
                    } catch (error) {
                        alert('保存失败：' + error.message);
                    }
                }

                onMounted(() => {
                    sessionId.value = localStorage.getItem('sessionId');
                    msLoginToken.value = localStorage.getItem('msLoginToken');
                    mserp.value = localStorage.getItem('mserp');
                    token.value = localStorage.getItem('auth_token');
                    hasToken.value = token.value && token.value != '' ? true : false;
                    msUsername.value = localStorage.getItem('msUsername');
                    msPassword.value = localStorage.getItem('msPassword');
                    if (sessionId.value && token.value) {
                        loadCountries();
                    }
                });

                return {
                    hasToken,
                    hasSession,
                    sessionId,
                    msLoginToken,
                    mserp,
                    token,
                    countries,
                    loadCountries,
                    selectedCountry,
                    config,
                    products,
                    productLoading,
                    productLoaded,
                    couponAmount,
                    showPreview,
                    previewData,
                    stats,
                    loadCountryConfig,
                    loadProducts,
                    previewProduct,
                    handleCountryChange,
                    handleProductUpdate,
                    downloadKillConfig,
                    downloadDiscountConfig,
                    clickBlankToClose,
                    markOutOfStock,
                    msUsername,
                    msPassword,
                    msLoading,
                    autoGetMsToken,
                    activeTab,
                    priceFormula,
                    formulaConstants,
                    formulaValid,
                    formulaError,
                    testValues,
                    testResult,
                    parseFormula,
                    calculateTestResult,
                    hasFormulaChanged,
                    confirmFormula
                };
            }
        }).mount('#app');
    </script>
</body>
</html>
